package cn.piesat.scanning.business.xz.algorithm;

import cn.piesat.scanning.business.common.algorithm.dataScan.DataScanAbstract;
import cn.piesat.scanning.business.common.algorithm.dataScan.DataScanParams;
import cn.piesat.scanning.business.dq1043.vo.ExtentVO;
import cn.piesat.scanning.business.dq1043.vo.MetaDataInDbVO;
import cn.piesat.scanning.business.xz.vo.ProjectionInfo;
import cn.piesat.scanning.dto.*;
import cn.piesat.scanning.service.DbDmsAlgorithmResultStoreService;
import cn.piesat.scanning.service.DbDmsSchedulerTaskFileRecordService;
import cn.piesat.scanning.service.DbDmsValidationService;
import cn.piesat.scanning.service.HtScanningMetadataService;
import cn.piesat.scanning.utils.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 数据入库插件
 *
 * @author xhl
 */
@Component
@Slf4j
public class XzDataScan extends DataScanAbstract {

    private static final Logger logger = LoggerFactory.getLogger(XzDataScan.class);

    @Autowired
    private KafkaConsumer kafkaConsumer;
    @Autowired
    private HtScanningMetadataService htScanningMetadataService;
    @Autowired
    private DbDmsSchedulerTaskFileRecordService dbDmsSchedulerTaskFileRecordService;
    @Autowired
    private DbDmsAlgorithmResultStoreService dbDmsAlgorithmResultStoreService;
    @Autowired
    private DbDmsValidationService dbDmsValidationService;


    private void splitValidationFileName(String fileName, DbDmsScanningValidationDTO dto) {
        String[] nameSplit = fileName.split("_");
        if (fileName.contains("FY4A")) {
            //FY4A-_AGRI--_N_DISK_1047E_L1-_FDI-_MULT_NOM_20190520040000_20190520041459_4000M_V0001.HDF
            //  0     1    2    3   4    5   6    7    8      9              10          11     12
            dto.setSatellite(nameSplit[0].replace("-", ""));
            dto.setSensor(nameSplit[1].replace("-", ""));
            dto.setResolution(formatResolution(nameSplit[11]));
            dto.setDataLevel(nameSplit[5].replace("-", ""));
            dto.setFileDate(nameSplit[9].replace("-", ""));
            dto.setProductIdentify(nameSplit[6].replace("-", ""));
        }
        if (fileName.contains("H08")) {
            //NC_H08_20200817_0620_L2CLP010_FLDK.02401_02401.nc
            // 0  1    2        3   4
            dto.setSatellite(nameSplit[1]);
            dto.setFileDate(nameSplit[2] + nameSplit[3] + "00");
            String dataLevel = nameSplit[4].substring(0, 2);
            dto.setDataLevel(dataLevel);
            String productIdentify = nameSplit[4].substring(2, 5);
            dto.setProductIdentify(productIdentify);
        }
    }

    @Override
    public void assembleAux(List<Object> pojoList, HtPathConfigurationDTO pathDTO, File file,
                            Set<String> existFileNameSet, String auxType) {
        if (auxType.equals("T799")) {
            DbDmsScanningMetadataAuxInfoDTO auxInfoDTO = new DbDmsScanningMetadataAuxInfoDTO();
            String fileName = file.getName();
            if (existFileNameSet.contains(fileName)) {
                return;
            }
            ResourceBundle resourceBundle = ResourceBundle.getBundle("meteorologicalElement");
            Set<String> keys = resourceBundle.keySet();
            for (String key : keys) {
                if (fileName.contains(key)) {
                    auxInfoDTO.setFileWant(key);
                    try {
                        auxInfoDTO.setFileWantRemark(new String(resourceBundle.getString(key).getBytes("ISO-8859-1"), "UTF-8"));
                    } catch (UnsupportedEncodingException e) {
                        logger.error("字符类型出现异常{}", e.getMessage(), e);
                    }
                    break;
                }
            }
            String[] split = fileName.split("\\.");
            auxInfoDTO.setFileTimeSecond(Integer.valueOf(split[1]));
            auxInfoDTO.setFileDate(split[0].substring(split[0].length() - 10) + "0000");
            String filePath = file.toString().substring(pathDTO.getScanningPath().length());
            auxInfoDTO.setFileName(fileName);
            auxInfoDTO.setFilePath(filePath);
            auxInfoDTO.setFileSize(file.length());
            pojoList.add(auxInfoDTO);
        }
    }

    @Override
    public void assembleDist(List<Object> pojoList, HtPathConfigurationDTO pathDTO, File file, Set<String> existFileNameSet, DataScanParams dataScanParams) {
        HtScanningMetadataDTO metadataDTO = new HtScanningMetadataDTO();
        String fileName = file.getName();
        String path = file.toString().substring(pathDTO.getScanningPath().length());
        if (existFileNameSet.contains(fileName)) {
            return;
        }
        List<HtScanningMetadataDTO> htScanningMetadata = htScanningMetadataService.findAllByFileName(fileName);
        if (!htScanningMetadata.isEmpty()) {
            for (HtScanningMetadataDTO htScanningMetadataDTO : htScanningMetadata) {
                htScanningMetadataService.deleteOne(htScanningMetadataDTO);
            }
        }
        //拆分数据
        splitFileName(fileName, metadataDTO, file.getAbsolutePath());
        metadataDTO.setFilePath(path);
        metadataDTO.setFileName(fileName);
        metadataDTO.setFileSize(file.length());
        metadataDTO.setPathConfigId(pathDTO.getId());
        metadataDTO.setFileType(fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase());
        metadataDTO.setCreateTime(new Date());
        pojoList.add(metadataDTO);

    }

    public void saveRedisData(String taskId, HtPathConfigurationDTO pathDTO) {
        Map<String, MetaDataInDbVO> inputMap = new HashMap<>();
        //先去redis中获取数据，去重获取任务计划号，根据任务计划号去任务记录表中查询是否有正在执行的数据，有，不动，
        // 没有就删除对应计划号的数据（源数据表、任务记录表、结果记录表）
        Jedis jedis = RedisUtil.getJedis();
        try {
            String result = jedis.hget("WaitList:", "1043");
            if (StringUtils.isNotBlank(result) && !("[]").equals(result)) {
                List<String> deleteTaskPlanIds = new ArrayList<>();
                List<MetaDataInDbVO> list = JSON.parseArray(result, MetaDataInDbVO.class);
                List<String> taskPlanIds = list.stream().map(p -> p.getTaskPlanId()).distinct().collect(Collectors.toList());
                for (String taskPlanId : taskPlanIds) {
                    List<DbDmsSchedulerTaskFileRecordDTO> recordList = dbDmsSchedulerTaskFileRecordService.findByTaskPlanIdAndStateNot(taskPlanId, 2);
                    if (recordList.size() == 0 || recordList == null) {
                        deleteTaskPlanIds.add(taskPlanId);
                    }
                }
                //根据任务计划号删除对应的数据
                dbDmsSchedulerTaskFileRecordService.deleteByTaskPlanIdIn(deleteTaskPlanIds);
                htScanningMetadataService.deleteByTaskPlanIdIn(deleteTaskPlanIds);
                dbDmsAlgorithmResultStoreService.deleteByTaskPlanIdIn(deleteTaskPlanIds);
                dbDmsValidationService.deleteByTaskPlanIdIn(deleteTaskPlanIds);
                //执行中的数据，需存到redis中
                List<MetaDataInDbVO> executeList = list.stream().filter(p -> !deleteTaskPlanIds.contains(p.getTaskPlanId())).collect(Collectors.toList());
                //需要入库的数据
                List<MetaDataInDbVO> inputList = list.stream().filter(p -> deleteTaskPlanIds.contains(p.getTaskPlanId())).collect(Collectors.toList());
                jedis.hset("WaitList:", "1043", JSON.toJSON(executeList).toString());
                for (MetaDataInDbVO vo : inputList) {
                    File file = new File(pathDTO.getScanningPath() + File.separator + vo.getFilePath());
                    String fileName = file.getName();
                    inputMap.put(fileName, vo);
                }
                List<String> inputNameList = new ArrayList<>(inputMap.keySet());
                //往记录表里增加记录
                dbDmsSchedulerTaskFileRecordService.prepareDataByFileNameList(taskId, inputNameList);
                ExecutorService threadPool = Executors.newFixedThreadPool(10);
                for (String fileName : inputNameList) {
                    threadPool.execute(() -> {
                        dbDmsSchedulerTaskFileRecordService.dataExecution(taskId, fileName);
                        MetaDataInDbVO dataVO = inputMap.get(fileName);
                        dbDmsSchedulerTaskFileRecordService.updateTaskPlanIdByTaskIdAndFileName(taskId, fileName, dataVO.getTaskPlanId());
                        HtScanningMetadataDTO metadataDTO = kafkaDataTransMetadata(dataVO, pathDTO);
                        htScanningMetadataService.addEntity(metadataDTO, taskId);
                    });
                }
                threadPool.shutdown();
            }
        } catch (Exception e) {
            logger.error("redis解析入库失败{}", e.getMessage());
        } finally {
            jedis.close();
        }
    }

    @Override
    public void kafkaSave(String taskId, HtPathConfigurationDTO pathDTO) {
        //从redis中将之前未入库的数据判断入库
        saveRedisData(taskId, pathDTO);
        //从kafka中获取数据
        ConsumerRecords<String, String> records = kafkaConsumer.poll(Duration.ofMillis(100000));
        Map<String, MetaDataInDbVO> distinctRecordMap = new HashMap<>();
        records.forEach(record -> {
            String value = record.value();
            MetaDataInDbVO metaDataInDbVO = null;
            try {
                metaDataInDbVO = JSON.parseObject(value, MetaDataInDbVO.class);
            } catch (Exception e) {
                logger.error("Kafka数据格式化异常{},{}", e.getMessage(), value);
            }
            if (metaDataInDbVO != null) {
                List<MetaDataInDbVO> dataList = new ArrayList<>();
                if ("L0".equals(metaDataInDbVO.getDataLevel())) {
                    File dir = new File(pathDTO.getScanningPath() + File.separator + metaDataInDbVO.getFilePath());
                    if (dir.exists() && dir.isDirectory()) {
                        File[] l0Files = dir.listFiles();
                        for (File f : l0Files) {
                            MetaDataInDbVO l0DataVO = copyVO(metaDataInDbVO);
                            l0DataVO.setFilePath(l0DataVO.getFilePath() + File.separator + f.getName());
                            dataList.add(l0DataVO);
                        }
                    }
                } else {
                    dataList.add(metaDataInDbVO);
                }
                for (MetaDataInDbVO vo : dataList) {
                    File file = new File(pathDTO.getScanningPath() + File.separator + vo.getFilePath());
                    String fileName = file.getName();
                    distinctRecordMap.put(fileName, vo);
                }
            }
        });
        //获得所有的文件名称集合
        List<String> execFileNameList = new ArrayList<>(distinctRecordMap.keySet());
        if (execFileNameList.size() > 0 && execFileNameList != null) {
            //根据任务id和文件名集合 从扫描记录表里获取status为2的数据包含（文件名、任务计划号）--已经录入过的数据，此次是回放的文件
            List<DbDmsSchedulerTaskFileRecordDTO> existList = dbDmsSchedulerTaskFileRecordService.findByFileNameList(execFileNameList, taskId);
            //获取回放数据的任务计划号
            List<String> taskPlanIds = existList.stream().map(p -> p.getTaskPlanId()).distinct().collect(Collectors.toList());
            List<String> saveResisFileName = new ArrayList<>();
            List<String> deleteTaskPlanIds = new ArrayList<>();
            for (String taskPlanId : taskPlanIds) {
                List<DbDmsSchedulerTaskFileRecordDTO> recordList = dbDmsSchedulerTaskFileRecordService.findByTaskPlanIdAndStateNot(taskPlanId, 2);
                if (recordList.size() > 0 && recordList != null) {
                    saveResisFileName = recordList.stream().map(p -> p.getFileName()).collect(Collectors.toList());
                    deleteTaskPlanIds.add(taskPlanId);
                    execFileNameList.removeAll(saveResisFileName);
                }
            }
            taskPlanIds.removeAll(deleteTaskPlanIds);
            List<MetaDataInDbVO> saveRedisList = new ArrayList<>();
            for (String name : saveResisFileName) {
                MetaDataInDbVO a = distinctRecordMap.get(name);
                if (a != null) {
                    saveRedisList.add(a);
                }
            }
            Jedis jedis1 = RedisUtil.getJedis();
            try {
                String res = jedis1.hget("WaitList:", "1043");
                List<MetaDataInDbVO> redisList = new ArrayList<>();
                if (StringUtils.isNotBlank(res)) {
                    redisList = JSON.parseArray(res, MetaDataInDbVO.class);
                }
                redisList.addAll(saveRedisList);
                jedis1.hset("WaitList:", "1043", JSON.toJSON(redisList).toString());
            } catch (Exception e) {
                logger.error("redis解析入库失败{}", e.getMessage());
            } finally {
                jedis1.close();
            }
            //根据任务计划号删除源数据表、任务记录表、结果记录表对应的数据
            dbDmsSchedulerTaskFileRecordService.deleteByTaskPlanIdIn(taskPlanIds);
            htScanningMetadataService.deleteByTaskPlanIdIn(taskPlanIds);
            dbDmsAlgorithmResultStoreService.deleteByTaskPlanIdIn(taskPlanIds);
            //删除质检源结果相关表对应的数据
            dbDmsValidationService.deleteByTaskPlanIdIn(taskPlanIds);
            //往记录表里增加记录
            dbDmsSchedulerTaskFileRecordService.prepareDataByFileNameList(taskId, execFileNameList);
            ExecutorService threadPool = Executors.newFixedThreadPool(30);
            for (String fileName : execFileNameList) {
                threadPool.execute(() -> {
                    dbDmsSchedulerTaskFileRecordService.dataExecution(taskId, fileName);
                    MetaDataInDbVO dataVO = distinctRecordMap.get(fileName);
                    dbDmsSchedulerTaskFileRecordService.updateTaskPlanIdByTaskIdAndFileName(taskId, fileName, dataVO.getTaskPlanId());
                    HtScanningMetadataDTO metadataDTO = kafkaDataTransMetadata(dataVO, pathDTO);
                    htScanningMetadataService.addEntity(metadataDTO, taskId);
                });
            }
            threadPool.shutdown();
        }

        if (records.count() > 0) {
            kafkaConsumer.commitAsync();
        }
    }

    public static void main(String[] args) {
        //GF6_WFV_E74.1_N31.4_20230621_L1A1420326398-2.tiff

//        String[] nameSplit = "BAS_CLM-_GBAL_L2_FY3D_MERSI_1000M_GLL_HHMM_20230703_0835.NC".split("_");
        String fileName = "FY3D_MWRID_GBAL_L1_20231225_2014_010KM_MS.HDF";
        String[] nameSplit = fileName.split("_");
        if (fileName.endsWith("FY3D_MWRI") && fileName.endsWith(".HDF") && nameSplit[3].equals("L1")){
            System.out.println("111");
        }

    }

    /**
     * 获取文件名称中的 卫星、传感器、分辨率、等级、日期等信息
     * PS：因各个卫星命名规则不同，当接入新的数据时需增加对应文件名称 [格式分割代码]
     *
     * @param fileName  文件名称
     * @param entityDto 实体类
     */
    private void splitFileName(String fileName, HtScanningMetadataDTO entityDto, String filePath) {


        String[] nameSplit = fileName.split("_");
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
        //RNSCA-RVIRS_npp_d20230822_t1257_svi01.h5
        //RNSCA-RVIRS_npp_d20230822_t1257_svm01.h5
        if (fileName.startsWith("RNSCA-RVIRS") || fileName.endsWith(".h5")) {
            entityDto.setSatellite("NPP");
            entityDto.setSensor("NPP");
            entityDto.setRegion("GBAL");
            entityDto.setDataLevel("L1");
            entityDto.setProductIid("NPP");
            entityDto.setFileDate(nameSplit[2].replace("d", "")+nameSplit[3].replace("t", "")+"00");
        }
//T45RYQ_20230718T043709_B01_20m.jp2
        if (fileName.endsWith("_B01_20m.jp2") || fileName.endsWith("SCL_20m.jp2")) {
            entityDto.setSatellite("S2B");
            entityDto.setSensor("MODIS");
            entityDto.setRegion("GBAL");
            entityDto.setDataLevel("L1");
            entityDto.setProductIid("S2B");
            entityDto.setFileDate(nameSplit[1].replace("T", ""));
        }
            //FY3D_MWRIA_GBAL_L1_20231225_2247_010KM_MS.HDF
        System.out.println(fileName);
        if (fileName.startsWith("FY3D_MWRI") && fileName.endsWith(".HDF") && nameSplit[3].equals("L1")) {
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion(nameSplit[2]);
            entityDto.setDataLevel(nameSplit[3]);
            entityDto.setProductIid("FY3D_MWRI");
            entityDto.setFileDate(nameSplit[4]+nameSplit[5]+"00");
        }
        if (fileName.startsWith("LC08") && fileName.endsWith("B1.TIF")
                || fileName.startsWith("LC08") && fileName.endsWith("T1_MTL.xml")
                || fileName.startsWith("LC09") && fileName.endsWith("B1.TIF")
                || fileName.startsWith("LC09") && fileName.endsWith("T1_MTL.xml")
                || fileName.startsWith("LC08") && fileName.endsWith("T1_QA_PIXEL.TIF")
                || fileName.startsWith("LC09") && fileName.endsWith("T1_QA_PIXEL.TIF")
        ) {
            //LC08_L2SP_132035_20230523_20230602_02_T1_SR_B1.TIF
            //LC08_L2SP_132035_20230523_20230602_02_T1_MTL.xml
            //LC09_L2SP_141041_20230514_20230516_02_T1_SR_B1.TIF
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setDataLevel(nameSplit[1]);
            entityDto.setRegion("GBAL");
            entityDto.setProductIid(nameSplit[0]);
            entityDto.setFileDate(nameSplit[3] + nameSplit[2]);
        }
        //AQUA_X_2023_07_04_03_55_D_G.MOD021KM.hdf
        //AQUA_X_2023_07_06_14_41_A_G.MOD03.hdf
        //TERRA_X_2023_07_31_22_50_A_G.MOD021KM.hdf
        //TERRA_X_2023_07_23_11_20_D_G.MOD03.hdf
        if (fileName.startsWith("AQUA_X") && fileName.endsWith(".hdf")
                || fileName.startsWith("TERRA_X") && fileName.endsWith(".hdf")) {
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor("MODIS");
            entityDto.setRegion("GBAL");
            entityDto.setOrbitId(nameSplit[7]);
            entityDto.setDataLevel("L1");
            entityDto.setProductIid(nameSplit[8].replace(".hdf", "").replace("G.", ""));
            entityDto.setFileDate(nameSplit[2] + nameSplit[3] + nameSplit[4] + nameSplit[5] + nameSplit[6] + "00");
        }
        //FY3D原始数据
        if (fileName.contains("FY3D") && fileName.startsWith("Z_SATE_C_BAWX") && fileName.endsWith(".HDF")) {
            //Z_SATE_C_BAWX_20230701062104_P_FY3D_MERSI_GBAL_L1_20230701_0550_1000M_MS.HDF
            //Z_SATE_C_BAWX_20230701062106_P_FY3D_MERSI_GBAL_L1_20230701_0550_GEO1K_MS.HDF
            entityDto.setSatellite(nameSplit[6]);
            entityDto.setSensor(nameSplit[7]);
            entityDto.setRegion(nameSplit[8]);
            entityDto.setDataLevel(nameSplit[9]);
            entityDto.setProductIid("L1");
            entityDto.setFileDate(nameSplit[10] + nameSplit[11] + "00");
        }
        //FY3D原始数据 FY3E原始数据
        if (fileName.startsWith("FY3D_X")||fileName.startsWith("FY3E_X") && fileName.endsWith("L1B.HDF")) {
            //FY3D_X_2023_08_22_03_07_D_G_MERSI_1000M_L1B.HDF
            //FY3E_X_2023_08_22_06_23_D_G_MERSI_1000M_L1B.HDF
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[9]);
            entityDto.setRegion("GBAL");
            entityDto.setDataLevel("L1");
            entityDto.setProductIid("L1");
            entityDto.setFileDate(nameSplit[2] + nameSplit[3] + nameSplit[4] + nameSplit[5] + nameSplit[6] + "00");
        }
        //NOAA18原始数据|NOAA19原始数据
        if (fileName.startsWith("NOAA18") || fileName.startsWith("NOAA19") && fileName.endsWith(".L1b")) {
            //NOAA18_AVHRR_2023_01_15_00_21_A_G.L1b
            //NOAA19_AVHRR_2023_01_08_22_48_A_G.L1b
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion("GBAL");
            entityDto.setDataLevel("L1");
            entityDto.setProductIid("L1");
            entityDto.setFileDate(nameSplit[2] + nameSplit[3] + nameSplit[4] + nameSplit[5] + nameSplit[6] + "00");
        }
        //积雪所需预报数据
        if (fileName.startsWith("Z_NWGD_C_BELS") && fileName.endsWith(".GRB2")) {
            //Z_NWGD_C_BELS_20231120143021_P_RFFC_SPCC-PPH_202311202000_24003.GRB2
            entityDto.setSatellite(nameSplit[1]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion("ALL");
            entityDto.setDataLevel("L0");
            entityDto.setProductIid(nameSplit[7]);
            entityDto.setFileDate(nameSplit[8]);
        }
        //GF1原始数据
        if ((fileName.startsWith("GF1") && fileName.endsWith("tiff")) && nameSplit.length == 6
                || (fileName.startsWith("GF1") && fileName.endsWith("xml")) && nameSplit.length == 6
                ) {
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion("GBAL");
            entityDto.setProductIid(nameSplit[0]);
            entityDto.setDataLevel("L1");
            ProjectionInfo projectionInfo;
            if ("tiff".equals(fileType)) {
                String replaceXml = filePath.replace("tiff", "xml");
                projectionInfo = initProjection(replaceXml);
            } else {
                projectionInfo = initProjection(filePath);
            }
            if (null == projectionInfo || StringUtils.isEmpty(projectionInfo.getStartTime())) {
                entityDto.setFileDate("");
            } else {
                entityDto.setFileDate(projectionInfo.getStartTime());
            }
        }

        if ((fileName.startsWith("GF6") && fileName.endsWith("tiff")) && nameSplit.length == 6
                || (fileName.startsWith("GF6") && fileName.endsWith("xml")) && nameSplit.length == 6
        ) {
            //GF6_WFV_E74.1_N31.4_20230621_L1A1420326398-2.tiff
            System.out.println(fileName);
            String[] split = nameSplit[5].split("-");
            entityDto.setSatellite(nameSplit[0]);

            entityDto.setRegion("GBAL");
            entityDto.setProductIid(nameSplit[0]);
            entityDto.setDataLevel("L1");
            ProjectionInfo projectionInfo;
            if ("tiff".equals(fileType)) {
                entityDto.setSensor(nameSplit[1]+split[1].charAt(0));
                String replaceXml = filePath.replace("-"+split[1].charAt(0)+".tiff", ".xml");
                projectionInfo = initProjection(replaceXml);
            } else {
                entityDto.setSensor(nameSplit[1]);
                projectionInfo = initProjection(filePath);
            }
            if (null == projectionInfo || StringUtils.isEmpty(projectionInfo.getStartTime())) {
                entityDto.setFileDate("");
            } else {
                entityDto.setFileDate(projectionInfo.getStartTime());
            }
        }
        if ((fileName.startsWith("GF2") && fileName.endsWith("tiff")) && nameSplit.length == 6
                || (fileName.startsWith("GF2") && fileName.endsWith("xml")) && nameSplit.length == 6) {
            //GF2原始数据
            //GF2_PMS1_E89.2_N29.4_20220621_L1A0006540513-MSS1.tiff
            //GF2_PMS1_E89.2_N29.4_20220621_L1A0006540513-MSS1.xml
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion("GBAL");
            String[] split = nameSplit[5].split("-");
            entityDto.setProductIid(split[1].substring(0,4));
            entityDto.setDataLevel("L1");
            ProjectionInfo projectionInfo;
            if ("tiff".equals(fileType)) {
                String replaceXml = filePath.replace("tiff", "xml");
                projectionInfo = initProjection(replaceXml);
            } else {
                projectionInfo = initProjection(filePath);
            }
            if (null == projectionInfo || StringUtils.isEmpty(projectionInfo.getStartTime())) {
                entityDto.setFileDate("");
            } else {
                entityDto.setFileDate(projectionInfo.getStartTime());
            }
        }

        if (fileName.contains("FY3D_MERSI") && nameSplit.length == 8 && "L1".equals(nameSplit[3])) {
            //FY3D_MERSI_GBAL_L1_20220702_0720_GEO1K_MS.HDF
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion(nameSplit[2]);
            entityDto.setDataLevel(nameSplit[3]);
            entityDto.setFileDate(nameSplit[4] + nameSplit[5] + "00");
            entityDto.setProductIid("L1");
        }
        if (fileName.contains("GF") && fileName.contains("TIFF") && nameSplit.length == 9 && nameSplit[3].contains("L1")) {
            //GF1_WFV1_GBAL_L1F_GLL_20220705_113223_16M_MSS.TIFF
            entityDto.setSatellite(nameSplit[0]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setRegion(nameSplit[2]);
            entityDto.setDataLevel(nameSplit[3]);
            entityDto.setFileDate(nameSplit[5] + nameSplit[6]);
            entityDto.setResolution(formatResolution(nameSplit[7]));
            entityDto.setProductIid(nameSplit[3]);
        }

        if (fileName.startsWith("Z_SATE_C_BAWX_") && fileName.contains("FY4A") &&  fileName.endsWith(".HDF")) {
            //Z_SATE_C_BAWX_20230823023730_P_FY4A-_AGRI--_N_REGC_1047E_L1-_GEO-_MULT_NOM_20230823023000_20230823023417_4000M_V0001.HDF
            entityDto.setSatellite(nameSplit[6].replace("-", ""));
            entityDto.setSensor(nameSplit[7].replace("-", ""));
            entityDto.setResolution(formatResolution(nameSplit[17]));
            entityDto.setDataLevel(nameSplit[11].replace("-", ""));
            entityDto.setFileDate(nameSplit[15]);
            entityDto.setRegion(nameSplit[9]);
            entityDto.setProductIid(nameSplit[12].replace("-", ""));
        }
        if (fileName.startsWith("FY4A-_AGRI--_N") && fileName.endsWith(".HDF")) {
            //
            //FY4A-_AGRI--_N_DISK_1047E_L1-_GEO-_MULT_NOM_20230726054500_20230726055959_4000M_V0001.HDF
            entityDto.setSatellite(nameSplit[0].replace("-", ""));
            entityDto.setSensor(nameSplit[1].replace("-", ""));
            entityDto.setResolution(formatResolution(nameSplit[11]));
            entityDto.setDataLevel(nameSplit[5].replace("-", ""));
            entityDto.setFileDate(nameSplit[9]);
            entityDto.setRegion(nameSplit[3]);
            entityDto.setProductIid(nameSplit[6].replace("-", ""));
        }
        if (fileName.startsWith("FY4A-_AGRI") && nameSplit[5].contains("L2-")) {
            //FY4A-_AGRI--_N_REGC_1047E_L2-_QPE-_MULT_GLL_20230809033000_20230809033417_4000M_VPRJ5.NC
            entityDto.setSatellite(nameSplit[0].replace("-", ""));
            entityDto.setSensor(nameSplit[1].replace("-", ""));
            entityDto.setResolution(formatResolution(nameSplit[9].substring(0, 4)));
            entityDto.setDataLevel(nameSplit[5].replace("-", ""));
            entityDto.setFileDate(nameSplit[9]);
            entityDto.setRegion(nameSplit[3]);
            entityDto.setProductIid(nameSplit[6].replace("-", ""));
        }
        if (fileName.contains("FY4A") && fileName.startsWith("FY4A_AGRI") && nameSplit[4].contains("L1")) {
            //FY4A_AGRI_DISK_1047E_L1A_FDI_GLL_20230723030000_20230723031459_4000M.NC
            //FY4A_AGRI_DISK_1047E_L1A_FDI_GLL_20230723030000_20230723031459_4000M.TIFF
            entityDto.setSatellite(nameSplit[0].replace("-", ""));
            entityDto.setSensor(nameSplit[1].replace("-", ""));
            entityDto.setResolution(formatResolution(nameSplit[9].substring(0, 4)));
            entityDto.setDataLevel(nameSplit[4].replace("-", ""));
            entityDto.setFileDate(nameSplit[7]);
            entityDto.setRegion(nameSplit[2]);
            entityDto.setProductIid(nameSplit[5].replace("-", ""));
        }
        if (fileName.startsWith("HS_H09") && fileName.endsWith(".DAT.bz2")
//        fileName.startsWith("HS_H09") && fileName.endsWith("R10_S0110.DAT.bz2")
        ) {
            //HS_H09_20231109_0320_B01_FLDK_R10_S0110.DAT.bz2
            entityDto.setSatellite(nameSplit[1]);
            entityDto.setSensor(nameSplit[1]);
            entityDto.setDataLevel("L1");
            entityDto.setFileDate(nameSplit[2]+nameSplit[3]+"00");
            entityDto.setRegion("GBAL");
            entityDto.setProductIid(nameSplit[1]);
        }


        if (fileName.contains("SURF") && fileName.contains(".json")) {
            //SURF_CHN_MUL_DAY_20230101000000.json
            //没有卫星内容，也建议存一个卫星，方便后续处理
            entityDto.setSatellite("FY3D");
            entityDto.setRegion(nameSplit[1]);
            entityDto.setProductIid(nameSplit[0]);
            entityDto.setProductMode(nameSplit[2]);
            entityDto.setDataLevel(nameSplit[3]);
            entityDto.setFileDate(nameSplit[4].replace(".json", ""));
        }
    }

    /**
     * 初始化projection，并填充信息
     *
     * @param xmlPath
     */
    public static ProjectionInfo initProjection(String xmlPath) {
        SAXReader reader = new SAXReader();
        try {
            File file = new File(xmlPath);
            if (!file.exists()) {
                return null;
            }
            Document document = reader.read(file);
            Element root = document.getRootElement();

            ProjectionInfo pro = new ProjectionInfo();
            Element dataElement = root;// root.element("ProductMetaData");
            Element CenterTime = root.element("CenterTime");
            pro.setStartTime(CenterTime != null ? CenterTime.getTextTrim().replace("-", "")
                    .replace(" ", "").replace(":", "") : "");
            // 基本信息
            // 卫星
            Element satellite = root.element("SatelliteID");
            pro.setSatellite(satellite != null ? satellite.getTextTrim() : "");
            // 传感器
            Element sensor = root.element("SensorID");
            pro.setSensor(sensor != null ? sensor.getTextTrim() : "");
            // 轨道号
            Element orbitID = root.element("OrbitID");
            pro.setOrbitNum(orbitID != null ? orbitID.getTextTrim() : "");

            // 产品类型
            Element productType = root.element("ProduceType");
            pro.setProductType(productType != null ? productType.getTextTrim() : "");

            return pro;

        } catch (DocumentException e) {
            logger.error("xml解析失败，请检查文件正确性。[{}]", xmlPath);
            return null;
        }
    }

    private String formatResolution(String str) {
        if (str.endsWith("KM")) {
            str = String.valueOf(Integer.parseInt(str.substring(0, str.indexOf("KM"))) * 1000);
        } else if (str.endsWith("M")) {
            str = str.replace("M", "");
        }
        return str;
    }

    private MetaDataInDbVO copyVO(MetaDataInDbVO sourceVO) {
        MetaDataInDbVO resultVO = new MetaDataInDbVO();
        resultVO.setTaskPlanId(sourceVO.getTaskPlanId());
        resultVO.setSubPlanId(sourceVO.getSubPlanId());
        resultVO.setStation(sourceVO.getStation());
        resultVO.setOrbitId(sourceVO.getOrbitId());
        resultVO.setObsMode(sourceVO.getObsMode());
        resultVO.setViewMode(sourceVO.getViewMode());
        resultVO.setFilePath(sourceVO.getFilePath());
        resultVO.setDataTime(sourceVO.getDataTime());
        resultVO.setSatellite(sourceVO.getSatellite());
        resultVO.setSensor(sourceVO.getSensor());
        resultVO.setResolution(sourceVO.getResolution());
        resultVO.setDataLevel(sourceVO.getDataLevel());
        resultVO.setProductId(sourceVO.getProductId());
        resultVO.setProductMode(sourceVO.getProductMode());
        resultVO.setCoordinate(sourceVO.getCoordinate());
        resultVO.setComRatio(sourceVO.getComRatio());
        resultVO.setBands(sourceVO.getBands());
        resultVO.setExtent(sourceVO.getExtent());
        return resultVO;
    }

    /**
     * kafka数据格式转换为源数据格式
     *
     * @param dataVO  kafka数据
     * @param pathDTO 路径对象
     * @return
     */
    private HtScanningMetadataDTO kafkaDataTransMetadata(MetaDataInDbVO dataVO, HtPathConfigurationDTO pathDTO) {
        HtScanningMetadataDTO metadataDTO = new HtScanningMetadataDTO();
        if (StringUtils.isNotBlank(dataVO.getId())) {
            metadataDTO.setId(dataVO.getId());
        }
        //解析景号、段号
        String[] pathSplit = dataVO.getFilePath().split("/");
        metadataDTO.setViewNumber(pathSplit[pathSplit.length - 2]);
        File file = new File(pathDTO.getScanningPath() + File.separator + dataVO.getFilePath());
        String fileName = file.getName();
        if (!dataVO.getDataLevel().toUpperCase().equals("L0")) {
            //解析中心经度和纬度
            String[] fileNameSplit = fileName.split("_");
            metadataDTO.setLon(fileNameSplit[5]);
            metadataDTO.setLat(fileNameSplit[6]);
        }
        metadataDTO.setSatellite(dataVO.getSatellite());
        metadataDTO.setSensor(dataVO.getSensor());
        metadataDTO.setResolution(dataVO.getResolution());
        metadataDTO.setDataLevel(dataVO.getDataLevel());
        metadataDTO.setFilePath(dataVO.getFilePath().replaceAll("/+", "/"));
        metadataDTO.setFileDate(dataVO.getDataTime());
        metadataDTO.setFileSize(file.length());
        metadataDTO.setFileName(fileName);
        if (fileName.lastIndexOf(".") != -1) {
            metadataDTO.setFileType(fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase());
        }
        metadataDTO.setCreateTime(new Date());
        metadataDTO.setPathConfigId(pathDTO.getId());
        metadataDTO.setTaskPlanId(dataVO.getTaskPlanId());
        metadataDTO.setSubPlanId(dataVO.getSubPlanId());
        metadataDTO.setStation(dataVO.getStation());
        metadataDTO.setOrbitId(dataVO.getOrbitId());
        metadataDTO.setObsMode(dataVO.getObsMode());
        metadataDTO.setViewMode(dataVO.getViewMode());
        metadataDTO.setProductIid(dataVO.getProductId());
        metadataDTO.setProductMode(dataVO.getProductMode());
        metadataDTO.setCoordinate(dataVO.getCoordinate());
        metadataDTO.setComRatio(dataVO.getComRatio());
        metadataDTO.setBands(dataVO.getBands());
        ExtentVO extent = dataVO.getExtent();
        if (extent != null) {
            metadataDTO.setTopleftLat(extent.getTopleftLat());
            metadataDTO.setTopleftLon(extent.getTopleftLon());
            metadataDTO.setToprightLat(extent.getToprightLat());
            metadataDTO.setToprightLon(extent.getToprightLon());
            metadataDTO.setBottomrightLat(extent.getBottomrightLat());
            metadataDTO.setBottomrightLon(extent.getBottomrightLon());
            metadataDTO.setBottomleftLat(extent.getBottomleftLat());
            metadataDTO.setBottomleftLon(extent.getBottomleftLon());
            String polygon = new StringBuilder()
                    .append("Polygon((")
                    .append(extent.getTopleftLon()).append(" ").append(extent.getTopleftLat()).append(",")
                    .append(extent.getBottomleftLon()).append(" ").append(extent.getBottomleftLat()).append(",")
                    .append(extent.getBottomrightLon()).append(" ").append(extent.getBottomrightLat()).append(",")
                    .append(extent.getToprightLon()).append(" ").append(extent.getToprightLat()).append(",")
                    .append(extent.getTopleftLon()).append(" ").append(extent.getTopleftLat())
                    .append("))").toString();
            WKTReader wktReader = new WKTReader();
            Geometry geometry;
            try {
                geometry = wktReader.read(polygon);
            } catch (ParseException e) {
                geometry = null;
            }
            metadataDTO.setAddressLoc(geometry);
        }
        return metadataDTO;
    }
}
